
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mwm.h"



/*
    global array of pattern pointers feeds of of ID..see argv parseing...
*/
char * patArray[10000];

/*
** Routine to process matches
*/
static int match (  void* id, unsigned long index, void * data )
{
   //printf(" pattern matched: index= %d, id=%d, %s \n",   index, id, patArray[(int)id]  );
   printf(" pattern matched: index= %d, %s \n",   index,  patArray[1]  );
   return 0;
}


/*
*/
typedef struct
{
  unsigned char * b;
  int blen;
}BINARY;

/*
*/
int gethex( int c )
{
   
   if( c >= 'A' && c <= 'F' ) return c -'A' + 10;
   if( c >= 'a' && c <= 'f' ) return c -'a' + 10;
   if( c >= '0' && c <= '9' ) return c -'0';

   return 0;
}


BINARY  * converthexbytes( unsigned char * s)
{
   int      val, k=0, m;
   BINARY * p;
   int      len = strlen(s);

   printf("--input hex: %s\n",s);   

   p = malloc( sizeof(BINARY) );

   p->b   = malloc( len / 2 );
   p->blen= len / 2;

   while( *s )
   {
      val   = gethex(*s);
      s++;
      val <<= 4;

      if( !*s ) break; // check that we have 2 digits for hex, else ignore the 1st

      val |= gethex(*s);
      s++;

      p->b[k++] = val;
   }

   if( k != p->blen )
   {
      printf("hex length mismatch\n");
   }

   printf("--output hex[%d]: ",p->blen); for(m=0;m<p->blen;m++) printf("%2.2x", p->b[m]);

   printf(" \n");

   return p;
}

/*
   Synthetic data
*/
BINARY * syndata( int nbytes, int irand, int repchar )
{
   BINARY * p =(BINARY*)malloc( sizeof(BINARY) );
   if( ! p ) return 0;
 
   p->b    = (unsigned char *)malloc( nbytes );
   if( ! p->b ) return 0;
   p->blen = nbytes;

   if( irand )
   {
     int i;

     srand( time(0) );

     for(i=0;i<nbytes;i++)
     {
        p->b[i] = (unsigned)( rand() & 0xff );
     }

   }
   else
   {
       memset(p->b,repchar,nbytes);
   }
   return p;
}


int randpat( unsigned char * s, int imin )
{
    int i,len;

    static int first=1;

    if( first )
    {
       first=0;
       srand(time(0));
    }

    while( 1 )
    {
       len = rand() & 0xf; //max of 15 bytes 
       if( len >= imin ) break;
    }
    

    for(i=0;i<len;i++)
    {
        s[i] = 'a' + ( rand() % 26 ); // a-z
    }

    s[len]=0;

    printf("--%s\n",s);
    return len;
}



int  main ( int argc, char ** argv )
{
   unsigned char *T, *text;
   int            n,textlen; 
   int            nmatches, i, bm = 0;
   
   int            npats=0, len, stat, nocase=0;
   BINARY        *p;
   int            irep=0,irand=0,isyn=0,nrep=1024,repchar=0;

   if( argc < 5 )
   {
      printf("usage: %s [-rand|-rep -n bytes -c|ch repchar -pr npats minlen ] -t|th TextToSearch -nocase [-pr numpats] -p|ph pat1 -p|ph pat2 -p|ph pat3\n",argv[0]);
      exit(1);
   }

   /* -- Allocate a Pattern Matching Structure - and Init it. */
   MWM_STRUCT  *ps = mwmNew();

   for(i=1;i<argc;i++)
   {
       if( strcmp(argv[i],"-nocase")==0 )
       {
          nocase = 1;
       }
       if( strcmp(argv[i],"-p")==0 )
       {
          i++;
          npats++;
          patArray[npats] = argv[i];
          len = strlen( argv[i] );

          //mwmAddPatternEx( ps, (unsigned char*)argv[i], len, nocase, 0, 0, (void*)npats /* ID */, 3000 /* IID -internal id*/ );
		  mwmAddPatternEx( ps, (unsigned char*)argv[i], len, nocase, 0, 0, (void*)argv[i] /* ID */, 3000 /* IID -internal id*/ );
       }
       if( strcmp(argv[i],"-ph")==0 )
       {
          i++;
          npats++;
          patArray[npats] = argv[i];
          p = converthexbytes( argv[i] );

          //mwmAddPatternEx( ps, p->b, p->blen, 1 /* nocase*/, 0, 0, (void*)npats /* ID */, 3000 /* IID -internal id*/ );
		  mwmAddPatternEx( ps, p->b, p->blen, 1 /* nocase*/, 0, 0, (void*)argv[i] /* ID */, 3000 /* IID -internal id*/ );
       }
       if( strcmp(argv[i],"-pr")==0 )
       {
          int m = atoi( argv[++i] );
          int imin = atoi( argv[++i] );
          int k;
          npats = 0;
          for(k=0;k<m;k++)
          {
             unsigned char px[256];
             int           len = randpat( px, imin );
             npats++;
             patArray[npats] = (unsigned char *)malloc( len+1 );
             sprintf(patArray[npats],"%s",px);
             mwmAddPatternEx( ps, px, len, 0 /* nocase*/, 0, 0, (void*)npats /* ID */, 3000 /* IID -internal id*/ );
          }
       }
       if( strcmp(argv[i],"-rand")==0 )
       {
          irand = 1;
          isyn  = 1;
       }
       if( strcmp(argv[i],"-rep")==0 )
       {
          irep  = 1;
          isyn  = 1;
       }
       if( strcmp(argv[i],"-n")==0 )
       {
          nrep = atoi( argv[++i] );
          isyn  = 1;
       }
       if( strcmp(argv[i],"-c")==0 )
       {
          repchar = argv[++i][0];
          isyn  = 1;
       }
       if( strcmp(argv[i],"-ch")==0 )
       {
          BINARY * px = converthexbytes( argv[++i] );
          repchar = px->b[0];
          isyn  = 1;
       }
       if( strcmp(argv[i],"-t")==0 )
       {
          i++;
          text = argv[i];
          textlen=strlen(text);
       }
       if( strcmp(argv[i],"-th")==0 )
       {
           i++;
           p = converthexbytes( argv[i] );
           text = p->b;
           textlen = p->blen;
       }
   }

   /* generate synthetic text */
   if( isyn )
   {
        
       p = syndata( nrep, irand, repchar );
       text = p->b;
       textlen = p->blen;
   }

   /* --- Preprocess Patterns */
   mwmPrepPatterns( ps );  


   /* ---- Do a multi-pattern search in the Text */
   stat = mwmSearch( (void*)ps, (unsigned char*)text, textlen, match, text);

   if( stat == 0 )
   {
       printf("no pattern matches\n");
   }else{
       printf("%d pattern matches in list\n",stat);
   }

   return 0;
}



